package DAOs;

import DAOs.exceptions.NonexistentEntityException;
import Entity.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

/**
 *
 * @author USUARIO
 */
public class ReforestationZoneJpaController implements Serializable {

    public ReforestationZoneJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(ReforestationZone reforestationZone) {
        if (reforestationZone.getSatellitalImages() == null) {
            reforestationZone.setSatellitalImages(new ArrayList<SatellitalImage>());
        }
        if (reforestationZone.getVisits() == null) {
            reforestationZone.setVisits(new ArrayList<Visit>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Farm farm = reforestationZone.getFarm();
            if (farm != null) {
                farm = em.getReference(farm.getClass(), farm.getId());
                reforestationZone.setFarm(farm);
            }
            Peasant peasant = reforestationZone.getPeasant();
            if (peasant != null) {
                peasant = em.getReference(peasant.getClass(), peasant.getId());
                reforestationZone.setPeasant(peasant);
            }
            List<SatellitalImage> attachedSatellitalImages = new ArrayList<SatellitalImage>();
            for (SatellitalImage satellitalImagesSatellitalImageToAttach : reforestationZone.getSatellitalImages()) {
                satellitalImagesSatellitalImageToAttach = em.getReference(satellitalImagesSatellitalImageToAttach.getClass(), satellitalImagesSatellitalImageToAttach.getId());
                attachedSatellitalImages.add(satellitalImagesSatellitalImageToAttach);
            }
            reforestationZone.setSatellitalImages(attachedSatellitalImages);
            List<Visit> attachedVisits = new ArrayList<Visit>();
            for (Visit visitsVisitToAttach : reforestationZone.getVisits()) {
                visitsVisitToAttach = em.getReference(visitsVisitToAttach.getClass(), visitsVisitToAttach.getId());
                attachedVisits.add(visitsVisitToAttach);
            }
            reforestationZone.setVisits(attachedVisits);
            em.persist(reforestationZone);
            if (farm != null) {
                farm.getReforestationZone().add(reforestationZone);
                farm = em.merge(farm);
            }
            if (peasant != null) {
                peasant.getZones().add(reforestationZone);
                peasant = em.merge(peasant);
            }
            for (SatellitalImage satellitalImagesSatellitalImage : reforestationZone.getSatellitalImages()) {
                ReforestationZone oldReforestationZoneOfSatellitalImagesSatellitalImage = satellitalImagesSatellitalImage.getReforestationZone();
                satellitalImagesSatellitalImage.setReforestationZone(reforestationZone);
                satellitalImagesSatellitalImage = em.merge(satellitalImagesSatellitalImage);
                if (oldReforestationZoneOfSatellitalImagesSatellitalImage != null) {
                    oldReforestationZoneOfSatellitalImagesSatellitalImage.getSatellitalImages().remove(satellitalImagesSatellitalImage);
                    oldReforestationZoneOfSatellitalImagesSatellitalImage = em.merge(oldReforestationZoneOfSatellitalImagesSatellitalImage);
                }
            }
            for (Visit visitsVisit : reforestationZone.getVisits()) {
                ReforestationZone oldReforestationZoneOfVisitsVisit = visitsVisit.getReforestationZone();
                visitsVisit.setReforestationZone(reforestationZone);
                visitsVisit = em.merge(visitsVisit);
                if (oldReforestationZoneOfVisitsVisit != null) {
                    oldReforestationZoneOfVisitsVisit.getVisits().remove(visitsVisit);
                    oldReforestationZoneOfVisitsVisit = em.merge(oldReforestationZoneOfVisitsVisit);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(ReforestationZone reforestationZone) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ReforestationZone persistentReforestationZone = em.find(ReforestationZone.class, reforestationZone.getId());
            Farm farmOld = persistentReforestationZone.getFarm();
            Farm farmNew = reforestationZone.getFarm();
            Peasant peasantOld = persistentReforestationZone.getPeasant();
            Peasant peasantNew = reforestationZone.getPeasant();
            List<SatellitalImage> satellitalImagesOld = persistentReforestationZone.getSatellitalImages();
            List<SatellitalImage> satellitalImagesNew = reforestationZone.getSatellitalImages();
            List<Visit> visitsOld = persistentReforestationZone.getVisits();
            List<Visit> visitsNew = reforestationZone.getVisits();
            if (farmNew != null) {
                farmNew = em.getReference(farmNew.getClass(), farmNew.getId());
                reforestationZone.setFarm(farmNew);
            }
            if (peasantNew != null) {
                peasantNew = em.getReference(peasantNew.getClass(), peasantNew.getId());
                reforestationZone.setPeasant(peasantNew);
            }
            List<SatellitalImage> attachedSatellitalImagesNew = new ArrayList<SatellitalImage>();
            for (SatellitalImage satellitalImagesNewSatellitalImageToAttach : satellitalImagesNew) {
                satellitalImagesNewSatellitalImageToAttach = em.getReference(satellitalImagesNewSatellitalImageToAttach.getClass(), satellitalImagesNewSatellitalImageToAttach.getId());
                attachedSatellitalImagesNew.add(satellitalImagesNewSatellitalImageToAttach);
            }
            satellitalImagesNew = attachedSatellitalImagesNew;
            reforestationZone.setSatellitalImages(satellitalImagesNew);
            List<Visit> attachedVisitsNew = new ArrayList<Visit>();
            for (Visit visitsNewVisitToAttach : visitsNew) {
                visitsNewVisitToAttach = em.getReference(visitsNewVisitToAttach.getClass(), visitsNewVisitToAttach.getId());
                attachedVisitsNew.add(visitsNewVisitToAttach);
            }
            visitsNew = attachedVisitsNew;
            reforestationZone.setVisits(visitsNew);
            reforestationZone = em.merge(reforestationZone);
            if (farmOld != null && !farmOld.equals(farmNew)) {
                farmOld.getReforestationZone().remove(reforestationZone);
                farmOld = em.merge(farmOld);
            }
            if (farmNew != null && !farmNew.equals(farmOld)) {
                farmNew.getReforestationZone().add(reforestationZone);
                farmNew = em.merge(farmNew);
            }
            if (peasantOld != null && !peasantOld.equals(peasantNew)) {
                peasantOld.getZones().remove(reforestationZone);
                peasantOld = em.merge(peasantOld);
            }
            if (peasantNew != null && !peasantNew.equals(peasantOld)) {
                peasantNew.getZones().add(reforestationZone);
                peasantNew = em.merge(peasantNew);
            }
            for (SatellitalImage satellitalImagesOldSatellitalImage : satellitalImagesOld) {
                if (!satellitalImagesNew.contains(satellitalImagesOldSatellitalImage)) {
                    satellitalImagesOldSatellitalImage.setReforestationZone(null);
                    satellitalImagesOldSatellitalImage = em.merge(satellitalImagesOldSatellitalImage);
                }
            }
            for (SatellitalImage satellitalImagesNewSatellitalImage : satellitalImagesNew) {
                if (!satellitalImagesOld.contains(satellitalImagesNewSatellitalImage)) {
                    ReforestationZone oldReforestationZoneOfSatellitalImagesNewSatellitalImage = satellitalImagesNewSatellitalImage.getReforestationZone();
                    satellitalImagesNewSatellitalImage.setReforestationZone(reforestationZone);
                    satellitalImagesNewSatellitalImage = em.merge(satellitalImagesNewSatellitalImage);
                    if (oldReforestationZoneOfSatellitalImagesNewSatellitalImage != null && !oldReforestationZoneOfSatellitalImagesNewSatellitalImage.equals(reforestationZone)) {
                        oldReforestationZoneOfSatellitalImagesNewSatellitalImage.getSatellitalImages().remove(satellitalImagesNewSatellitalImage);
                        oldReforestationZoneOfSatellitalImagesNewSatellitalImage = em.merge(oldReforestationZoneOfSatellitalImagesNewSatellitalImage);
                    }
                }
            }
            for (Visit visitsOldVisit : visitsOld) {
                if (!visitsNew.contains(visitsOldVisit)) {
                    visitsOldVisit.setReforestationZone(null);
                    visitsOldVisit = em.merge(visitsOldVisit);
                }
            }
            for (Visit visitsNewVisit : visitsNew) {
                if (!visitsOld.contains(visitsNewVisit)) {
                    ReforestationZone oldReforestationZoneOfVisitsNewVisit = visitsNewVisit.getReforestationZone();
                    visitsNewVisit.setReforestationZone(reforestationZone);
                    visitsNewVisit = em.merge(visitsNewVisit);
                    if (oldReforestationZoneOfVisitsNewVisit != null && !oldReforestationZoneOfVisitsNewVisit.equals(reforestationZone)) {
                        oldReforestationZoneOfVisitsNewVisit.getVisits().remove(visitsNewVisit);
                        oldReforestationZoneOfVisitsNewVisit = em.merge(oldReforestationZoneOfVisitsNewVisit);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = reforestationZone.getId();
                if (findReforestationZone(id) == null) {
                    throw new NonexistentEntityException("The reforestationZone with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ReforestationZone reforestationZone;
            try {
                reforestationZone = em.getReference(ReforestationZone.class, id);
                reforestationZone.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The reforestationZone with id " + id + " no longer exists.", enfe);
            }
            Farm farm = reforestationZone.getFarm();
            if (farm != null) {
                farm.getReforestationZone().remove(reforestationZone);
                farm = em.merge(farm);
            }
            Peasant peasant = reforestationZone.getPeasant();
            if (peasant != null) {
                peasant.getZones().remove(reforestationZone);
                peasant = em.merge(peasant);
            }
            List<SatellitalImage> satellitalImages = reforestationZone.getSatellitalImages();
            for (SatellitalImage satellitalImagesSatellitalImage : satellitalImages) {
                satellitalImagesSatellitalImage.setReforestationZone(null);
                satellitalImagesSatellitalImage = em.merge(satellitalImagesSatellitalImage);
            }
            List<Visit> visits = reforestationZone.getVisits();
            for (Visit visitsVisit : visits) {
                visitsVisit.setReforestationZone(null);
                visitsVisit = em.merge(visitsVisit);
            }
            em.remove(reforestationZone);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<ReforestationZone> findReforestationZoneEntities() {
        return findReforestationZoneEntities(true, -1, -1);
    }

    public List<ReforestationZone> findReforestationZoneEntities(int maxResults, int firstResult) {
        return findReforestationZoneEntities(false, maxResults, firstResult);
    }

    private List<ReforestationZone> findReforestationZoneEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(ReforestationZone.class));
            Query q = em.createQuery(cq);
            Query q1 = em.createNativeQuery("Select ID from reforestationzone");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
                q1.setMaxResults(maxResults);
                q1.setFirstResult(firstResult);
            }
            List<ReforestationZone> reforestationZonesList = q.getResultList();
            for (int i = 0; i < reforestationZonesList.size(); i++) {
                reforestationZonesList.get(i).setId((Long) q1.getResultList().get(i));
            }
            return reforestationZonesList;
        } finally {
            em.close();
        }
    }

    public ReforestationZone findReforestationZone(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(ReforestationZone.class, id);
        } finally {
            em.close();
        }
    }

    public int getReforestationZoneCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<ReforestationZone> rt = cq.from(ReforestationZone.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
}
